﻿using System;
using System.Collections;
using System.Threading;

namespace ABCThread
{
    class Program
    {
        static void Main(string[] args)
        {
            var aEvent = new AutoResetEvent(false);
            var bEvent = new AutoResetEvent(false);
            var cEvent = new AutoResetEvent(false);
            

            var ta = new Thread(()=> {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("A");
                    bEvent.Set();
                    aEvent.WaitOne();
                }
                //如果不再次把线程唤醒，那么  b  c 就会一直处于等待状态
                bEvent.Set();
            });
            var tb = new Thread(() => {
                // 为了让a线程先执行，就先把 bc线程设置为等待
                bEvent.WaitOne();
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("B");
                    cEvent.Set();
                    bEvent.WaitOne();
                }
                cEvent.Set();
            });
            var tc = new Thread(() => {
                cEvent.WaitOne();
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("C");
                    aEvent.Set();
                    cEvent.WaitOne();
                }
            });

            ta.Start();
            tb.Start();
            tc.Start();

            //new Thread(()=> {
            //    while (true)
            //    {
            //        Console.WriteLine($"a->{ta.ThreadState};b->{tb.ThreadState}; c->{tc.ThreadState}");

            //        Thread.Sleep(2000);
            //    }
            
            //}).Start();



        }
    }



    public class CountDownLatch
    {
        private object lockObj = new Object();
        private int counter;

        public CountDownLatch(int counter)
        {
            this.counter = counter;
        }

        public void Await()
        {
            lock (lockObj)
            {
                while (counter > 0)
                {
                    Monitor.Wait(lockObj);
                }
            }
        }

        public void CountDown()
        {
            lock (lockObj)
            {
                counter--;
                Monitor.PulseAll(lockObj);
            }
        }
    }


}
